package com.jax.pronet.bo;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * User: Lucy
 * Date: 15/10/12
 * Time: 14:22
 */
public class Graph
{
  private final Map<String, List<String>> peopleToRecommendations;
  private static final double DAMPENING_FACTOR = 0.85;

  public Graph(Network network)
  {
    assert network != null;
    this.peopleToRecommendations = new HashMap<String, List<String>>();
    for(Programmer programmer: network.getListOfProgrammers())
    {
      this.peopleToRecommendations.put(programmer.getName(), programmer.getListOfRecommendations());
    }
  }
  
  public Map<String, Double> calculateKudos()
  {
    Map<String, Double> currentKudos = initialiseKudosMap();
    double averageKudos = 0.;
    while (Math.abs(averageKudos - 1) > 0.000001)
    {
      Map<String, Double> amountContributed = initialiseKudosMap();
      for(String programmer: peopleToRecommendations.keySet())
      {
        double howManyRecommendations = peopleToRecommendations.get(programmer).size();
        double currentKudosForProgrammer = currentKudos.get(programmer);
        double amountToContribute = currentKudosForProgrammer / howManyRecommendations;
        for(String recommendee: peopleToRecommendations.get(programmer))
        {
          double existKudos =  amountContributed.get(recommendee);
          amountContributed.put(recommendee, amountToContribute + existKudos);
        }
      }

      double runningKudos = 0.;
      for(String programmer: amountContributed.keySet())
      {
        double kudos = (1 - DAMPENING_FACTOR) + (DAMPENING_FACTOR * amountContributed.get(programmer));
        currentKudos.put(programmer, kudos);
        runningKudos += kudos;
      }
      averageKudos = runningKudos / amountContributed.size();
    }
    
    return currentKudos;
  }
  
  private Map<String, Double> initialiseKudosMap()
  {
    Map<String, Double> kudos = new HashMap<String, Double>();
    for(String programmer: peopleToRecommendations.keySet())
    {
      kudos.put(programmer, 0d);
    }
    return kudos;
  }
  
}